import React, {
    useState,
    useMemo,
    useEffect,
    CSSProperties,
    ReactNode
} from 'react';

import styled from 'styled-components'; 

import { color } from '../shared/style';

import Button from '../button';
import { Icon } from '../icon';

const PageUl = styled.ul`
	display: flex;
	justify-content: center;
	align-items: center;

	& > li {
		list-style: none;
	}
	& button {
		border-radius: 6px;
		padding: 10px 8px;
	}
	& span {
		line-height: 13.6px;
		height: 13.6px;
		min-width: 18px;
	}
	& svg {
		height: 13.6px;
		width: 13.6px;
		vertical-align: bottom;
	}
`;

function calculateMove(current: number, state: number[], totalPage: number): number[] | null {
	let mid = Math.floor(state.length / 2);
	let arr;
	let minus = current - state[mid];
	if (minus === 0) {
		arr = null;
	} else if (minus > 0) {
		let tmp = state[state.length - 1];
		if (tmp + minus < totalPage) {
			arr = state.map((v) => v + minus);
		} else {
			if (tmp === totalPage) {
				arr = null;
			} else {
				arr = state.map((v) => v + totalPage - tmp);
			}
		}
	} else {
		//负数
		if (state[0] + minus > 1) {
			arr = state.map((v) => v + minus);
		} else {
			//边缘，看最大能减几
			if (state[0] === 1) {
				arr = null;
			} else {
				arr = state.map((v) => v - state[0] + 1);
			}
		}
	}
	return arr;
}

type PaginationProps = {
    /** 每页显示多少条*/
	pageSize?: number;
	/** 默认显示第几页 */
	defaultCurrent?: number;
	/** 总共条数*/
	total: number;
	/** 分页条目最大显示长度 */
	barMaxSize?: number;
	/** 回调页数 */
	callback?: (v: number) => void;
	/** 外层style*/
	style?:CSSProperties;
	/**外层类名 */
	classnames?:string;
};

export function Pagination(props: PaginationProps) {
    const { callback } = props;
    const pageSize = 10;
    const defaultCurrent = 1;
    const barMaxSize = 5;
    const total = 1000;
    const [current, setCurrent] = useState(defaultCurrent);
    const [state, setState] = useState<Array<number>>([]);
    const totalPage = useMemo(() => {
		let number = Math.ceil(total / pageSize);
		if (number > barMaxSize) {
			let statetmp = new Array(barMaxSize).fill(1).map((_x, y) => y + 1);
			setState(statetmp);
			let arr = calculateMove(defaultCurrent, statetmp, number);
			if (arr) {
				setState(arr);
			}
		} else {
			let statetmp = new Array(number).fill(1).map((_x, y) => y + 1);
			setState(statetmp);
			let arr = calculateMove(defaultCurrent, statetmp, number);
			if (arr) {
				setState(arr);
			}
		}
		return number;
	}, [pageSize, total]);
    useEffect(() => {
        if(callback) callback(current)
    }, [callback, current]);
    return (
        <PageUl>
            <li>
                <Button 
                    appearance='primaryOutline'
                    disabled={current === 1? true : false}
                    onClick={() => {
                        if(state.length > 0){
                            if(state[0] > 1){
                                let statetmp = state.map((x) => x - 1);
                                setState(statetmp);
                                setCurrent(current - 1);
                                let arr = calculateMove(
                                    current - 1,
                                    statetmp,
                                    totalPage
                                );
                                if(arr){
                                    setState(arr);
                                }
                            }
                        }else if(current !== state[0]){
                            setCurrent(current - 1);
                            let arr = calculateMove(
                                current - 1,
                                state,
                                totalPage
                            );
                            if(arr){
                                setState(arr);
                            }
                        }
                    }}
                >
                    <Icon icon="arrowleft" color={color.primary}></Icon>
                </Button>
            </li>
            {
                state.map((x, i) => {
                    return (
                        <li key={i}>
                            <Button
                                appearance={current === x? 'primary' : 'primaryOutline'}
                                onClick={() => {
                                    setCurrent(x);
                                    let arr = calculateMove(x, state, totalPage);
                                    if(arr){
                                        setState(arr);
                                    }
                                }}
                            >
                                {x}
                            </Button>
                        </li>
                    )
                })
            }
            <li>
                <Button
                    appearance="primaryOutline"
                    disabled={current === totalPage ? true : false}
                    onClick={() => {
                        if (state.length > 0) {
                            if (state[barMaxSize! - 1] < totalPage) {
                                let statetmp = state.map((x) => x + 1);
                                setState(statetmp);
                                setCurrent(current + 1);
                                let arr = calculateMove(
                                    current + 1,
                                    statetmp,
                                    totalPage
                                );
                                if (arr) {
                                    setState(arr);
                                }
                            } else {
                                if (current !== totalPage) {
                                    setCurrent(current + 1);
                                    let arr = calculateMove(
                                        current + 1,
                                        state,
                                        totalPage
                                    );
                                    if (arr) {
                                        setState(arr);
                                    }
                                }
                            }
                        }
                    }}
                >
                    <Icon icon="arrowright" color={color.primary}></Icon>
                </Button>
            </li>
        </PageUl>
    )
}

Pagination.defaultProps = {
	pageSize: 10,
	defaultCurrent: 11,
	barMaxSize: 5,
	total: 1000,
};

const TableTable = styled.table`
	width: 100%;
	text-align: left;
	border-radius: 2px 2px 0 0;
	border-collapse: separate;
	border-spacing: 0;
	table-layout: auto;
	box-sizing: border-box;
	margin: 0;
	padding: 0;
	color: rgba(0, 0, 0, 0.65);
	font-variant: tabular-nums;
	line-height: 1.5715;
	list-style: none;
	font-feature-settings: "tnum";
	position: relative;
	z-index: 0;
	clear: both;
	font-size: 14px;
	background: #fff;
	border-radius: 2px;
	& > thead > tr > th {
		color: rgba(0, 0, 0, 0.85);
		font-weight: 500;
		text-align: left;
		background: #fafafa;
		border-bottom: 1px solid #f0f0f0;
		transition: background 0.3s ease;
		position: relative;
		padding: 16px;
		overflow-wrap: break-word;
	}
	& > tbody > tr {
		& > td {
			border-bottom: 1px solid #f0f0f0;
			transition: background 0.3s;
			position: relative;
			padding: 16px;
			overflow-wrap: break-word;
		}
		&:hover {
			& > td {
				background: #fafafa;
			}
		}
	}
`;

const TableHeadSpan = styled.span`
	display: inline-block;
	position: absolute;
	right: 0;
	top: 0;
	padding: 16px;
	cursor: pointer;
	& svg {
		height: 10px;
		width: 10px;
	}
`;

export interface SourceDataType {
  key: string;
  [key: string]: any;
}

export interface ColumnType {
  title: ReactNode;
  /** 排序等操作用来代替这列的 */
  dataIndex: string;
  sorter?: {
    compare: (a: SourceDataType, b: SourceDataType) => number;
  };
  render?: (v: any, value: SourceDataType, rowData: ColumnType) => ReactNode;
}

const MapData = (data: SourceDataType[], columnData: ColumnType[]) => {
  return data.map((v) => {
    return (
      <tr key={v.key}>
        {columnData.map((value, index) => {
          return (
            <td key={index}>
              <span>
                {value.render
                  ? value.render(v[value.dataIndex], v, value)
                  : v[value.dataIndex]}
              </span>
            </td>
          );
        })}
      </tr>
    );
  });
};

export type TableProps = {
  /** 表内数据部分 */
  data: SourceDataType[];
  /** 表头部分*/
  columns: ColumnType[];
  /** 是否开启排序 */
  sorted?: boolean;
  /** 是否开启页码 */
  pagination?: boolean;
  /** 开启页码时才有效，设置每页显示几个*/
  pageSize?: number;
}

export function Table(props: TableProps) {
  const { data, columns, pageSize, pagination, sorted } = props;
  const [columnData, setColumnData] = useState<ColumnType[]>([]);
  const [sourceData, setSourceData] = useState<SourceDataType[]>([]);
  const [paginationData, setPaginationData] = useState<SourceDataType[][]>([]);
  const [sortedData, setSortedData] = useState<SourceDataType[]>([]);
  const [filterState, setFilterState] = useState<number[]>([]);//记录第几列开启筛选
  const [current, setCurrent] = useState(0); //这个是paginationData的索引
  const originPagination = useMemo(() => {
    return (data: SourceDataType[]) => {
      let tmp: SourceDataType[][] = [];
      let len = data.length;
      let pagenumber = Math.ceil(len / pageSize!); //页数
      for (let i = 0; i < pagenumber; i++) {
        //每页该显示多少内容做好。
        tmp[i] = data.slice(
          0 + i * pageSize!,
          pageSize! + i * pageSize!
        );
      }
      setPaginationData(tmp);
    };
  }, [pageSize]);

  const totalColumn = useMemo(() => {
    //表头总长
    setColumnData(columns); //表头拿来渲染
    setFilterState(new Array(columns.length).fill(0));//初始化排序数据
    return columns.length;
  }, [columns]);

  const totalLen = useMemo(() => {
    //内容部分总长
    setSourceData(data); //数据
    if (pagination) {
      //分页走paginationData
      originPagination(data);
    }
    return data.length;
  }, [data, originPagination, pagination]);

  const renderData = useMemo(() => {
    //内容部分渲染
    let render;
    if (pagination && paginationData.length !== 0) {
      //如果分页，渲染分页
      render = MapData(paginationData[current], columnData);
    } else {
      //否则直接渲染
      if (sortedData.length === 0) {
        render = MapData(sourceData, columnData);
      } else {//如果排序有数据，就按排序渲染
        render = MapData(sortedData, columnData);
      }
    }
    return render;
  }, [columnData, current, pagination, paginationData, sortedData, sourceData]);

  return (
    <div>
      <TableTable>
        <thead>
          <tr>
            {columnData.map((v, i) => {
              return (
                <th key={i}>
                  <span>{v.title}</span>
                  {
                    v.sorter && sorted && v.sorter.compare && (
                      <TableHeadSpan
                        onClick={() => {
                          if (filterState[i]) {
                            //如果已经开启了排序
                            //查看是不是1，如果为1，进行逆序排序，否则清空
                            if (filterState[i] === 1) {
                              let res = sourceData
                                .slice()
                                .sort(
                                  (a, b) =>
                                    -v.sorter!.compare(
                                      a,
                                      b
                                    )
                                ); //数据传给compare
                              let newfilter = new Array(
                                totalColumn
                              ).fill(0);
                              newfilter[i] = 2;
                              setSortedData(res);
                              setFilterState(
                                newfilter
                              );
                            } else {
                              setSortedData([]); //清空排序数据
                              if (pagination) {
                                originPagination(
                                  data
                                );
                              }
                              filterState[i] = 0;
                              setFilterState([
                                ...filterState,
                              ]);
                            }
                          } else {
                            //没有开启就开启排序
                            let res = sourceData
                              .slice()
                              .sort(
                                v.sorter!.compare
                              ); //数据传给compare
                            let newfilter = new Array(
                              totalColumn
                            ).fill(0);
                            newfilter[i] = 1;
                            setSortedData(res);
                            setFilterState(newfilter);
                          }
                        }}
                      >
                        <Icon
                          icon="arrowup"
                          block
                          color={
                            filterState[i] === 1
                              ? color.primary
                              : color.dark
                          }
                        ></Icon>
                        <Icon
                          icon="arrowdown"
                          block
                          color={
                            filterState[i] === 2
                              ? color.primary
                              : color.dark
                          }
                        ></Icon>
                      </TableHeadSpan>
                    )
                  }
                </th>
              );
            })}
          </tr>
        </thead>
        <tbody>{renderData}</tbody>
      </TableTable>
      {
        pagination && (
          <Pagination
            style={{ justifyContent: "flex-end" }}
            total={totalLen}
            pageSize={pageSize}
            callback={(v) => setCurrent(v - 1)}
            defaultCurrent={1}
          ></Pagination>
        )
      }
    </div>
  );
}

Table.defaultProps = {
  sorted: false,
  pagination: false,
  pageSize: 10
};